package com.itheima.service.mongo.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.itheima.domain.mongo.UserLocation;
import com.itheima.domain.vo.UserLocationVo;
import com.itheima.service.mongo.UserLocationService;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Metrics;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class UserLocationServiceImpl implements UserLocationService {

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 保存或者更新实时位置
     *
     * 1.查询mongo中是否有该用户的地址数据
     * 2.如果没有 构建数据保存
     * 3.如果有 更新数据
     * @param latitude
     * @param longitude
     * @param addrStr
     * @param id
     */
    @Override
    public void save(String latitude, String longitude, String addrStr, Long id) {
        //1.查询mongo中是否有该用户的地址数据
        Query query = new Query(
                Criteria.where("userId").is(id)
        );
        UserLocation userLocation = mongoTemplate.findOne(query, UserLocation.class);
        //2.如果没有 构建数据保存
        if(userLocation == null){
            userLocation = new UserLocation();
            userLocation.setUserId(id);
            userLocation.setAddress(addrStr);
            userLocation.setCreated(System.currentTimeMillis());
            userLocation.setUpdated(System.currentTimeMillis());
            userLocation.setLastUpdated(System.currentTimeMillis());
            GeoJsonPoint point = new GeoJsonPoint(Double.valueOf(longitude) , Double.valueOf(latitude));
            userLocation.setLocation(point);
            mongoTemplate.save(userLocation);
        }else{
            //3.如果有 更新数据
            userLocation.setUpdated(System.currentTimeMillis());
            userLocation.setLastUpdated(System.currentTimeMillis());
            userLocation.setAddress(addrStr);
            GeoJsonPoint point = new GeoJsonPoint(Double.valueOf(longitude) , Double.valueOf(latitude));
            userLocation.setLocation(point);
            mongoTemplate.save(userLocation);
        }

    }

    /**
     * 查询附近人
     * @param loginUserId
     * @param distance
     * @return
     */
    @Override
    public List<Long> findNearUser(Long loginUserId, String distance) {

        Query query1 = new Query(
                Criteria.where("userId").is(loginUserId)
        );
        //1.获得该用户的坐标
        UserLocation userLocation = mongoTemplate.findOne(query1, UserLocation.class);

        //2.创建半径对象
        Distance dbDistance = new Distance( Integer.valueOf(distance)  , Metrics.KILOMETERS );

        //3.画圆(以点和半径画圆)  TODO 实际开发中记住除以1000
        Circle circle  = new Circle(userLocation.getLocation() , dbDistance);

        //4.查询坐落在圆上的点坐标
        Query query2 = new Query(
                Criteria.where("location").withinSphere(circle)
        );

        //查询
        List<UserLocation> userLocations = mongoTemplate.find(query2, UserLocation.class);
        List<Long> ids=  new ArrayList<>();
        //将集合数据转换成ids数据
        //UserLocation 中有一个GeoJsonPoint 对象  GeoJsonPoint对象没有实现序列化接口
        //dubbo所传输的所有的对象 必须实现序列化接口  所以此处我们需要转换成id的集合返回 防止报错
        if(CollectionUtil.isNotEmpty(userLocations)){
            for (UserLocation tempUserLocation : userLocations) {
                ids.add( tempUserLocation.getUserId()); //放入id
            }
        }
        return ids;
    }

    /*
     *
     *用户地理位置
     * @param userId  用户Id
     * @author
     * @date
     * @return java.util.Map<java.lang.String,java.lang.String>
     */

    @Override
    public Map<String,String> findByUserId(Long id) {

        Query query=new Query(
                Criteria.where("userId").is(id)
        );

        UserLocation location = mongoTemplate.findOne(query, UserLocation.class);


        //封装
        Map<String,String> map= new HashMap<>();
        map.put("address",location.getAddress());//位置
        map.put("longitude", UserLocationVo.format(location).getLongitude().toString());
        map.put("latitude", UserLocationVo.format(location).getLatitude().toString());

        return map;
    }

}
